﻿#region Header

/*
Behavioral Rating of Dancing Human Crowds based on Motion Patterns
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System.IO;
using Emgu.CV;
using Emgu.CV.Structure;
using paravili.Services;
using paravili.Steps;

#endregion

namespace paravili.CaptureSources {
	/// <summary>
	/// Represents a capture source that gets the images data as a raw video located on the harddisk.
	/// It is limited to the datatypes that are supported by the OpenCV framework
	/// </summary>
	public class RawVideoBasedCaptureSource : IDisposableCaptureSource {
		#region Public Properties

		[ConfigurabelStringValue(Name = "Path of the video")]
		public string VideoPath { get; set; }

		[ConfigurableNumericValue(Name = "Scale Factor", RangeFrom = 0, RangeTo = 3)]
		public int ScaleFactor { get; set; }

		#endregion

		#region Public Methods

		public RawVideoBasedCaptureSource() {
			ScaleFactor = 2;
		}

		#endregion

		private ICapture m_captureDevice;

		#region IDisposableCaptureSource Members

		[ConfigurabelStringValue(Name = "Name of the datasource")]
		public string Name { get; set; }

		public Image<Bgr, byte> QueryImage() {
			Image<Bgr, byte> toReturn = QueryFrame();
			if (toReturn == null) {
				DoInit();
				toReturn = QueryFrame();
			}
			return toReturn;
		}

		public void DoInit() {
			m_captureDevice = new Capture(VideoPath);
		}

		public void DoCleanUp() {
			m_captureDevice = null;
		}

		public bool IsAvailable {
			get { return File.Exists(VideoPath); }
		}

		#endregion

		public Image<Bgr, byte> QueryFrame() {
			if (m_captureDevice == null) {
				return null;
			}
			Image<Bgr, byte> toReturn = m_captureDevice.QueryFrame();
			if (toReturn == null) {
				return null;
			}
			for (int i = 0; i < ScaleFactor; i++) {
				toReturn = toReturn.PyrDown();
			}
			return toReturn;
		}
	}
}